package order

import (
	"booking/common/handler"
	"booking/common/utils"
	"booking/models"
	"gorm.io/gorm"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"github.com/xuri/excelize/v2"
)

// 上传并批量解析 Excel
func UploadAndParseExcel(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "文件上传失败: " + err.Error()})
		return
	}

	tmpDir := "./tmp"
	if err := os.MkdirAll(tmpDir, 0755); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建临时目录失败"})
		return
	}

	filePath := filepath.Join(tmpDir, file.Filename)
	if err := c.SaveUploadedFile(file, filePath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文件失败"})
		return
	}
	defer os.Remove(filePath)

	f, err := excelize.OpenFile(filePath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "打开 Excel 失败: " + err.Error()})
		return
	}
	defer func() { _ = f.Close() }()

	rows, err := f.Rows("总推送详表")
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "读取 Sheet 失败: " + err.Error()})
		return
	}
	defer func() { _ = rows.Close() }()

	// 跳过标题行
	rows.Next()

	var (
		orders        []models.Order
		orderCouriers []models.OrderCourier
		orderProducts []models.OrderProduct
		results       []int
		rowNum        = 1
		batchSize     = 100
	)
	results = make([]int, 0)
	for rows.Next() {
		rowNum++
		data, err := rows.Columns()
		if err != nil {
			results = append(results, rowNum)
			continue
		}

		orderNo := models.GenerateOrderNo()

		order := models.Order{
			OrderNo:         orderNo,
			PushNo:          SafeGet(data, 0),
			CustomerName:    SafeGet(data, 14),
			RecipientName:   SafeGet(data, 14),
			PushDate:        utils.ParseDate(SafeGet(data, 1)),
			PushTime:        SafeGet(data, 2),
			CompleteDate:    utils.ParseDate(SafeGet(data, 6)),
			TaxpayerNo:      SafeGet(data, 8),
			LayoutPerson:    SafeGet(data, 10),
			Registrant:      SafeGet(data, 11),
			LegalPersonName: SafeGet(data, 4),
			LegalPersonIdno: SafeGet(data, 16),
			ConsigneeCity:   SafeGet(data, 3),
			SignCompany:     SafeGet(data, 9),
			RecipientPhone:  SafeGet(data, 15),
			Attachments:     "[]",
			OriginalContent: strings.Join(data, ","),
		}

		orderCourier := models.OrderCourier{
			OrderNo:        orderNo,
			Courier:        SafeGet(data, 7),
			RecipientName:  SafeGet(data, 14),
			RecipientPhone: SafeGet(data, 15),
			RecipientCity:  SafeGet(data, 3),
			Attachments:    "[]",
			DeliveryTime:   utils.ParseDate(SafeGet(data, 1)),
		}

		orderProduct := models.OrderProduct{
			OrderNo:     orderNo,
			ProductDesc: "刻章",
			Quantity:    cast.ToInt(SafeGet(data, 5)),
			Remark:      strings.Join(data, ","),
		}

		orders = append(orders, order)
		orderCouriers = append(orderCouriers, orderCourier)
		orderProducts = append(orderProducts, orderProduct)

		// 每 100 条写入一次
		if len(orders) >= batchSize {
			if err := saveBatch(orders, orderCouriers, orderProducts); err != nil {
				results = append(results, rowNum)
			}
			orders = nil
			orderCouriers = nil
			orderProducts = nil
		}
	}

	// 插入最后一批
	if len(orders) > 0 {
		if err := saveBatch(orders, orderCouriers, orderProducts); err != nil {
			results = append(results, rowNum)
		}
	}

	handler.Success(map[string]any{
		"msg": "导入完成",
		"失败行": results,
	}, c)
}

// 批量写入数据库（事务内）
func saveBatch(orders []models.Order, couriers []models.OrderCourier, products []models.OrderProduct) error {
	return models.Db.Transaction(func(tx *gorm.DB) error {
		if err := tx.Create(&orders).Error; err != nil {
			return err
		}
		if err := tx.Create(&couriers).Error; err != nil {
			return err
		}
		if err := tx.Create(&products).Error; err != nil {
			return err
		}
		return nil
	})
}

// 防止越界
func SafeGet(data []string, index int) string {
	if index >= 0 && index < len(data) {
		return strings.TrimSpace(data[index])
	}
	return ""
}
